# encoding: utf-8

import httplib2

from gcapi.entry import Entry
from gcapi.calendar import Calendar

class GoogleService(object):
    '''Support the access to the google calendar 
    
    http://www.google.com/calendar 
    '''
    
    _DEFAULT_HEADERS = {'Content-Type': 'application/atom+xml'}
    _SEARCH_URI     = "http://www.google.com/calendar/feeds/default/private/full"
    _SEARCH_CALENDAR_URI = "http://www.google.com/calendar/feeds"
    
    _SEARCH_MAX = 9999
    
    def __init__(self, email, passwd):
        '''Initialize the service class to access to the google calendar
        
        @param email: The email to sign on to google service
        @param passwd: The password for the sign on.
        '''
        
        self._email = email
        self._passwd = passwd
        self._http = httplib2.Http()
        self._http.follow_all_redirects = True
        self._http.add_credentials(self._email, self._passwd)

    def getCalendars(self, maxResults=_SEARCH_MAX):
        '''return all calendars for the given email.
        
        @param maxResults: defines the max number of results to receive, default is _SEARCH_MAX = 9999

        @return: a list of gcapi.calendar.Calendar instances
        '''
        uri = "%s/%s?max-results=%d" % (GoogleService._SEARCH_CALENDAR_URI, self._email, maxResults)
        response, content = self._http.request(uri, "GET") #@UnusedVariable
        return Calendar.createFromText(content)

    def insert(self, calendar, entry):
        '''create a new entry in the calendar that is given.
        
        @param calendar: the calendar to insert the entry in
        @param entry: the calendar entry to add
        
        @return: true if the entry was inserted
        '''
        assert isinstance(calendar, Calendar)
        assert isinstance(entry, Entry)

        body = entry.asXML()
        
        response, content = self._http.request(calendar.linkAlternate, "POST", body=body, 
                                               headers=GoogleService._DEFAULT_HEADERS)
        if response.status == 201:
            entry.updateFromText(content)
        
        return response.status == 201
    
    
    def getEntries(self, calendar, maxResults=_SEARCH_MAX):
        '''return all entries in the given calendar (current max size is 25)
        
        @param maxResults: defines the result to receive, default is _SEARCH_MAX = 9999
        @param calendar: the calendar to receive the entries from
        
        @returns: the list of Entries received @see gcapi.entry.Entry
        '''
        
        assert isinstance(calendar, Calendar)
        uri = "%s?max-results=%d" % (calendar.linkAlternate, maxResults)
        response, content = self._http.request(uri, "GET") #@UnusedVariable
        return Entry.createFromText(content)
        
    def query(self, calendar, query, maxResults=_SEARCH_MAX, startDate=None, startMin=None, startMax=_SEARCH_MAX): #@UnusedVariable
        '''return all entries in the given calendar (current max size is 25) that match
        a query
        
        @param calendar: the calendar to receive the entries from
        @param query: a query string
        @param startDate: the start date in RFC 3339 format
        @param endDate: the end date in RFC 3339 format
        @param maxResults: defines the result to receive, default is _SEARCH_MAX = 9999
        
        @returns: the list of Entries received @see gcapi.entry.Entry
        '''
        
        assert isinstance(calendar, Calendar)
        minArg = ""
        maxArg = ""
        
        if startMin is not None:
            minArg = "&start-min=%s" % startMin
        
        # Parameter isn't supported
        #
        #if startMax is not None:
        #    maxArg = "&start-max=%s" % startMax
            
        uri = "%s?q=%s&max-results=%d%s%s" % (calendar.linkAlternate, query, maxResults, minArg, maxArg)
        response, content = self._http.request(uri, "GET") #@UnusedVariable
        
        return Entry.createFromText(content)
    
    def update(self, entry):
        '''Update the given entry and if the update was successfull, the result will be transferd, to
        the given entry. @see: gcapi.entry.Entry.updateFromText()
        
        @param entry: the entry to update
        
        @returns: true, if the entry could successfully be updated
        '''
        
        body = entry.asXML()
        
        response, content = self._http.request(entry.editURI, "PUT", body=body,
                                               headers=GoogleService._DEFAULT_HEADERS)
        
        if response.status == 200:
            entry.updateFromText(content)

        return response.status == 200
    
    def delete(self, entry):
        '''
        
        @param entry:
        '''
        
        response, content = self._http.request(entry.editURI, "DELETE") #@UnusedVariable
        
        return response.status == 200
    